﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VelocityShop.Entities;
using VelocityShop.Data;
using VelocityShop.Data.SQLServer;

namespace VelocityShop.Data.Velocity
{
    public  class VelocityCatalogProvider:ICatalogProvider 
    {
        private static CacheHelper _helper;

        public VelocityCatalogProvider()
        {
            _helper = new CacheHelper("CatalogCache"); 
        }

        public Catalog GetCatalog()
        {
            
            //verify if catalog exists in cache
            Catalog catalog = (Catalog)_helper.GetFromCache("Catalog1");

            if (catalog == null)
            {
                //load catalog from DB
                SQLServerCatalogProvider SQLServerCatalogProvider = new SQLServerCatalogProvider();

                catalog = SQLServerCatalogProvider.GetCatalog();

                //put catalog in cache
                _helper.PutInCache("Catalog1", catalog);

            }

            return catalog;

        }

        
        public IList<CatalogItem> GetItemsByCategoryId(string categoryId)
        {
            IEnumerable<KeyValuePair<string,object>> objectsInRegion;

            IList<CatalogItem> itemsInCategory =new List<CatalogItem>();

            objectsInRegion = _helper.GetAllObjectsInRegion(categoryId);

            if (objectsInRegion == null || objectsInRegion.Count() == 0)
            {                //load catalog items from DB
                SQLServerCatalogProvider SQLServerCatalogProvider = new SQLServerCatalogProvider();

                itemsInCategory = SQLServerCatalogProvider.GetItemsByCategoryId(categoryId);

                _helper.CreateRegion(categoryId);

                Parallel.ForEach(itemsInCategory, item =>{

                    //put each catalog item in cache
                    if (item.Tags==string.Empty)
                        _helper.PutInCache(item.ProductId, item, categoryId);
                    else
                        _helper.PutInCache(item.ProductId, item, categoryId, item.Tags);
                });

            }
            else
            {
                //Translating from into list
                foreach (KeyValuePair<string, object> item in objectsInRegion)
                {
                    itemsInCategory.Add((CatalogItem)item.Value);
                }

            }

            return itemsInCategory;
        }

        public void InsertCatalogItem(string categoryId, CatalogItem item)
        {
            //put each new item in cache
            _helper.PutInCache(item.ProductId, item, categoryId);
        }

        public void InsertCatalogItem(string categoryId, CatalogItem item, string tags)
        {
            //put each new item in cache
            _helper.PutInCache(item.ProductId, item, categoryId, tags);
        }

        public IList<CatalogItem> GetItemsByTag(string categoryId, string tag)
        {
            IEnumerable<KeyValuePair<string, object>> objectsByTag;

            IList<CatalogItem> itemsInCategory = new List<CatalogItem>();

            objectsByTag = _helper.GetObjectsByTag(categoryId,tag);

            if (objectsByTag == null)
            {

                return null;

            }
            else
            {
                //Translating from into list
                Parallel.ForEach(objectsByTag, item =>
                {

                    itemsInCategory.Add((CatalogItem)item.Value);
                });

            }

            return itemsInCategory;
        }

    }
}
